using System;
using System.Collections.Generic;

namespace CppWrapper.GeneratorService
{
  internal class TypeDependencyHandler
  {
    private readonly List<Type> dependentTypeHistory = new List<Type>();
    private readonly List<Type> doneTypes = new List<Type>();
    private readonly bool resolveDependencies;

    public TypeDependencyHandler(bool resolveDependencies)
    {
      this.resolveDependencies = resolveDependencies;
    }

    public void AddType(Type type)
    {
      if (!dependentTypeHistory.Contains(type) && !doneTypes.Contains(type) && !GeneratorServices.IgnoreBecauseOfDefinedAttributes(type))
      {
        dependentTypeHistory.Add(type);
      }
    }

    public void AddDependentType(Type type)
    {
      if (type.IsByRef || type.IsArray || type.IsPointer)
      {
        type = type.GetElementType();
      }

      if (type == typeof(object) || type == typeof(ValueType))
      {
        return;
      }
      if (GeneratorServices.IgnoreBecauseOfDefinedAttributes(type))
      {
        return;
      }
      if (GeneratorServices.IsTypeExcluded(type))
      {
        return;
      }
      if ((type.IsGenericType || resolveDependencies) && !type.IsArray)
      {
        if (!dependentTypeHistory.Contains(type) && !doneTypes.Contains(type))
        {
          dependentTypeHistory.Add(type);
        }
      }
    }


    public IList<Type> DependentTypes
    {
      get { return new List<Type> (dependentTypeHistory); }
    }

    public void MarkasWrapped(Type type)
    {
      if (dependentTypeHistory.Contains(type))
      {
        dependentTypeHistory.Remove(type);
        doneTypes.Add(type);
      }
    }
  }
}